package mxmf.utils;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import mxmf.entity.system.Partner;
import mxmf.enums.Constant;
import mxmf.enums.ContentTypeEnum;
import mxmf.enums.StatusEnum;

public class PoiExcelUtils {
      private static final Logger logger = LoggerFactory.getLogger(PoiExcelUtils.class);
	  public static final int BUFFER_SIZE = 100;
	  @SuppressWarnings("unused")
	  public static final int DEFAULT_SHEET_SIZE = 50000;
	  public static final String DEFAULT_SHEET_NAME = "sheet";
	  public static List<Partner>partners;
    public static void exportToPath(List<?> data,SXSSFWorkbook workbook,SXSSFSheet sxssfSheet,
            OutputStream outputStream,List<String> methodNames,String flag) {
        try {
            long exportStart = System.currentTimeMillis();
    	    List<?> objects =data;
    	    export2Sheet(sxssfSheet, methodNames, objects);
	        if(Constant.EXCEL_EXPORT_END.equals(flag)) {
	            objects = null;
	            workbook.write(outputStream);
                outputStream.flush();
                IOUtils.closeQuietly(outputStream);
                workbook.dispose();
	        }
    	    long exportEnd = System.currentTimeMillis();
    	    logger.info("导出excel耗时["+(exportEnd-exportStart)+"]");
	    } catch (IOException e) {
                logger.info("导出文件失败["+e.getMessage()+"]");
                IOUtils.closeQuietly(outputStream);
                workbook.dispose();
	    }
	  }
      
	  public static void exportToHtml(List<?> data,SXSSFWorkbook workbook,SXSSFSheet sxssfSheet,
	          List<String> methodNames,HttpServletResponse response,String fileName,String flag) {
	    OutputStream outputStream=null;
        try {
          List<?> objects =data;
          export2Sheet(sxssfSheet, methodNames, objects);
          if(Constant.EXCEL_EXPORT_END.equals(flag)) {
            objects = null;
            outputStream= response.getOutputStream();
            response.reset();
            response.setContentType("application/vnd.ms-excel;charset=utf-8");   
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName+".xlsx", "utf-8"));
            response.setCharacterEncoding("utf-8");    
            workbook.write(outputStream);
            outputStream.flush();
            IOUtils.closeQuietly(outputStream);
            workbook.dispose();
         }    
        } catch (IOException e) {
          logger.info("导出到网页失败["+e.getMessage()+"]");
          IOUtils.closeQuietly(outputStream);
          workbook.dispose();
        }
     }


	  private static void export2Sheet(SXSSFSheet sheet, List<String> getters, List<?> data) {

	    try {
	      int sheetRowCount = sheet.getLastRowNum();
	      SXSSFRow dataRow;
	      for (Object datum : data) {
	        dataRow = sheet.createRow(++sheetRowCount);
	        Class<?> clazz = datum.getClass();
	        XSSFRichTextString text;
	        Cell cell;
	        for (int i = 0; i < getters.size(); i++) {
	          String methodName = getters.get(i);
	          String value = getTextString(datum,clazz,methodName);
	          text = new XSSFRichTextString(value);
	          cell = dataRow.createCell(i);
	          cell.setCellValue(text);
	        }
	      }
	    } catch (Exception e) {
	      throw new RuntimeException(e);
	    }
	  }

	  public static SXSSFSheet createSheet(SXSSFWorkbook workbook, List<ExcelColumn> cols,
	      String sheetName) {
	    SXSSFSheet sheet = workbook.createSheet(sheetName);
	    SXSSFRow row = sheet.createRow(0);
	    ExcelColumn column;
	    SXSSFCell cell;
	    XSSFRichTextString text;
	    for (int i = 0; i < cols.size(); i++) {
	      column = cols.get(i);
	      cell = row.createCell(i);
	      text = new XSSFRichTextString(column.getName());
	      cell.setCellValue(text);
	      int width = column.getWidth();
	      if (width > 0) {
	        sheet.setColumnWidth(i, width);
	      }
	    }
	    return sheet;
	  }

	  private static String  getTextString(Object datum,Class<?> clazz, String methodName) {
	      try {
	      Method readMethod;
          Object o;
          Object o1;
          String text="";
          String baseTagsGetter="";
          readMethod = clazz.getMethod(methodName);
          o = readMethod.invoke(datum);
          if (o == null) {
                o = "";
             }
           String property =  lowerCaseHead(methodName.replace("get",""));
              switch (property) {
            case "copyrightEnd":
                baseTagsGetter = "get"+upperCaseHead("copyrightBegin");
                readMethod = clazz.getMethod(baseTagsGetter);
                o1 = readMethod.invoke(datum);
                if(o1 == null) {
                    o1 ="";
                 }
                text = o1.toString()+"~"+o.toString();
                break;
            case "validTime":
                baseTagsGetter = "get"+upperCaseHead("expireTime");
                readMethod = clazz.getMethod(baseTagsGetter);
                o1 = readMethod.invoke(datum);
                if(o1 == null) {
                    o1 ="";
                 }
                text = o.toString()+"~"+o1.toString();
                break;
            case "catalogStatus": //编目状态
                text = StatusEnum.CatalogStatusEnum.getNameByCode(o.toString());
                break;
            case "auditStatus": //审核状态
                text = StatusEnum.AuditStatusEnum.getNameByCode(o.toString());
                break;
            case "cdnStatus": //注入状态
                text = StatusEnum.CdnStatusEnum.getNameByCode(o.toString());
                break;
            case "enableStatus": //可用状态
                text = StatusEnum.EnableStatusEnum.getNameByCode(o.toString());
                break;
            case "type":
                text = ContentTypeEnum.getNameByCode(o.toString());
                break;
            case "cpCode": //内容提供商
                String code = o.toString();
                if(EmptyUtil.isNotEmpty(partners)) {
                    for (int i = 0; i < partners.size(); i++) {
                        if(code.equals(partners.get(i).getCode())) {
                            text =  partners.get(i).getName();
                            break;
                        }
                    }
                }
                break;
            default:
                text = o.toString();
                break;
            }
        return text;
        } catch (Exception e) {
            e.printStackTrace();
        } 
	      return "";
	  }
	  
	  
	  public static String upperCaseHead(String word) {
	    char[] chars = word.toCharArray();
	    int j = chars[0] - 32;
	    chars[0] = (char) j;
	    return new String(chars);
	  }
	  
	   private static String lowerCaseHead(String word) {
	        char[] chars = word.toCharArray();
	        int j = chars[0] + 32;
	        chars[0] = (char) j;
	        return new String(chars);
	      }
	   
}
